﻿using System;

namespace FIFP.Common
{
    /// <summary>
    /// Defines the interface of an object that allows a method call to be dispatched to
    /// another thread.
    /// </summary>
    public interface IDispatcher
    {
        #region Properties

        /// <summary>
        /// Gets a value indicating whether the caller is on a different thread to the one 
        /// this object represents, and therefore must use an invoke method to make the 
        /// required call.
        /// </summary>
        /// <value>true if the caller in on a different thread than the thread this object 
        /// represents; otherwise, false.</value>
        bool InvokeRequired
        {
            get;
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Invokes the specified action asynchronously on the thread this object represents.
        /// </summary>
        /// <param name="action">The action.</param>
        void BeginInvoke(Action action);

        /// <summary>
        /// Invokes the specified action asynchronously on the thread this object represents.
        /// </summary>
        /// <typeparam name="T">The parameter type.</typeparam>
        /// <param name="action">The action.</param>
        /// <param name="arg">The parameter.</param>
        void BeginInvoke<T>(Action<T> action, T arg);

        /// <summary>
        /// Invokes the specified action asynchronously on the thread this object represents.
        /// </summary>
        /// <typeparam name="T1">The type of the first arg.</typeparam>
        /// <typeparam name="T2">The type of the second arg.</typeparam>
        /// <param name="action">The action.</param>
        /// <param name="arg1">The first arg.</param>
        /// <param name="arg2">The second arg.</param>
        void BeginInvoke<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);

        /// <summary>
        /// Invokes the specified action synchronously on the thread this object represents.
        /// </summary>
        /// <param name="action">The action.</param>
        void Invoke(Action action);

        /// <summary>
        /// Invokes the specified action synchronously on the thread this object represents.
        /// </summary>
        /// <typeparam name="T">The parameter type.</typeparam>
        /// <param name="action">The action.</param>
        /// <param name="arg">The parameter.</param>
        void Invoke<T>(Action<T> action, T arg);

        /// <summary>
        /// Invokes the specified action synchronously on the thread this object represents.
        /// </summary>
        /// <typeparam name="T1">The type of the first arg.</typeparam>
        /// <typeparam name="T2">The type of the second arg.</typeparam>
        /// <param name="action">The action.</param>
        /// <param name="arg1">The first arg.</param>
        /// <param name="arg2">The second arg.</param>
        void Invoke<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);

        #endregion Methods
    }
}